//
//  MOImageLabel.m
//  MOPrefix
//
//  Created by alfie on 2021/1/29.
//

#import "MOImageLabel.h"
#import <Masonry/Masonry.h>
#import "QAFriendModel.h"
#import "QAConversation.h"
#import <CoreText/CoreText.h>

@interface MOImageLabel ()

/** 图片的size */
@property (nonatomic, assign) CGSize            imageSize;

/** 图片和文本的间距 */
@property (nonatomic, assign) CGFloat           titleSpaceImage;

/** 最大宽度 */
@property (nonatomic, assign) CGFloat           maxWidth;

/** 图片 */
@property (nonatomic, strong) UIImage           *image;

/** 是否需要绘制 */
@property (nonatomic, assign) BOOL             needsDisplay;

@property (nonatomic, assign) BOOL             needsAppendWidth;

@end
  

@implementation MOImageLabel

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.userInteractionEnabled = NO;
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]];
    }
    return self;
}


- (void)layoutAttributes {
    if (!self.needsDisplay || !self.image) return;
    
    // 如果不限制行数，不用考虑省略号的问题，直接拼接图片
    if (self.numberOfLines == 0 || !self.text.length) {
        [self appendImageToText:self.text];
        return;
    }
    
    CGFloat width = self.maxWidth > 0 ? self.maxWidth : self.frame.size.width;

    // 按行 分割字符串
    NSString *contentString = self.text;
    NSArray *array = [MOImageLabel getSeparatedLinesWithText:contentString andFonte:self.font andSize:CGSizeMake(width, self.frame.size.height)];
    int numberOfLines = (int)(MIN(array.count, self.numberOfLines));
    int lastIndex = numberOfLines - 1;
    NSString *lastStr = array[lastIndex];
    if (!array.count || !lastStr.length) {
        NSLog(@"-------------------------- 分割字符串出现异常：%@ --------------------------", array);
        [self appendImageToText:self.text];
        return;
    }
    // 计算最后一行字符串的size
    CGSize size = [lastStr boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : self.font} context:nil].size;
    CGFloat max_W = width - self.imageSize.width - self.titleSpaceImage;
    // 如果最后一行文字的长度，超出了最大长度，需要裁减，并拼接省略号
    if (size.width > max_W) {
        // 拼接字符串，最后一行不拼接，需要处理完最后一行字符串之后再拼接
        contentString = @"";
        for (int i = 0; i < lastIndex; i++) {
            contentString = [contentString stringByAppendingString:array[i]];
        }
        // 计算... 省略号的宽度
        CGFloat points_W = [@"..." boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : self.font} context:nil].size.width;
        // 截取在最大宽度 - 省略号宽度下，最后一行的文字显示的内容
        NSArray *lastLineArray = [MOImageLabel getSeparatedLinesWithText:lastStr andFonte:self.font andSize:CGSizeMake(max_W - ceil(points_W), self.frame.size.height)];
        lastStr = lastLineArray.firstObject;
        // contentString 拼接截取后的 最后一行字符串
        contentString = [NSString stringWithFormat:@"%@%@...", contentString, lastStr];
    }
    // 拼接图片
    [self appendImageToText:contentString];
}


#pragma mark - 布局
- (void)layoutSubviews {
    [super layoutSubviews];
    [self layoutAttributes];
}


- (void)appendImageToText:(NSString *)text {
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:text ?: @"" attributes:nil];
    if (self.titleSpaceImage > 0) {
        NSTextAttachment *spaceAttachment = NSTextAttachment.new;
        spaceAttachment.image = UIImage.new;
        spaceAttachment.bounds = CGRectMake(0, 0, self.titleSpaceImage, self.imageSize.height);
        NSAttributedString *spaceAttr = [NSAttributedString attributedStringWithAttachment:spaceAttachment];
        [attributeString appendAttributedString:spaceAttr];
    }

    NSTextAttachment *attachment = NSTextAttachment.new;
    attachment.image = self.image;
    CGFloat y = self.font.descender - self.imageSize.height/2 + self.font.descender + self.font.capHeight + 2;
    attachment.bounds = CGRectMake(0, y, self.imageSize.width, self.imageSize.height);
    NSAttributedString *attrImageStr = [NSAttributedString attributedStringWithAttachment:attachment];
    [attributeString appendAttributedString:attrImageStr];
    self.needsDisplay = NO;
    self.needsAppendWidth = YES;
    self.attributedText = attributeString;
}


#pragma mark - setter
- (void)setDelegate:(id<MOImageLabelDelegate>)delegate {
    _delegate = delegate;
    if (delegate) {
        self.userInteractionEnabled = YES;
    }
}


#pragma mark - 绑定数据
- (void)attachText:(NSString *)text image:(UIImage *)image titleSpaceImage:(CGFloat)titleSpaceImage imageSize:(CGSize)imageSize maxWidth:(CGFloat)maxWidth {
    
    self.image = image;
    self.maxWidth = maxWidth;
    self.titleSpaceImage = titleSpaceImage;
    self.imageSize = CGSizeEqualToSize(imageSize, CGSizeZero) ? image.size : imageSize;
    if (image) {
        self.needsDisplay = YES;
    }
    self.text = text;
}


#pragma mark - 显示昵称特殊展示
- (void)displayWithData:(id )data maxWidth:(CGFloat)maxWidth {
    NSString *title;
    if ([data isKindOfClass:QAUserInfoModel.class]) {
        QAUserInfoModel *model = data;
        title = model.nickName;
    } else if ([data isKindOfClass:QAFriendModel.class]) {
        QAFriendModel *model = data;
        title = model.collationGroupString;
    } else if ([data isKindOfClass:QAConversation.class]) {
        QAConversation *model = data;
        if (model.isGroup) {
            // 群聊
            /// 普通群
            [self attachText:model.groupName image:nil titleSpaceImage:0 imageSize:CGSizeZero maxWidth:maxWidth];
        } else {
            // 取单聊数据
            [self displayWithData:model.friendModel maxWidth:maxWidth];
        }
        return;
    } else {
        return;
    }
    
    [self attachText:title image:nil titleSpaceImage:0 imageSize:CGSizeZero maxWidth:maxWidth];
}


#pragma mark - 点击事件
- (void)tapAction {
    if ([self.delegate respondsToSelector:@selector(didSelectedImageLabel:)]) {
        [self.delegate didSelectedImageLabel:self];
    }
}


#pragma mark - 按行 分割文本
+ (NSArray *)getSeparatedLinesWithText:(NSString *)content andFonte:(UIFont *)font andSize:(CGSize)size {
    if (!(content && [content isKindOfClass:[NSString class]]) ||
        !(font && [font isKindOfClass:[UIFont class]]) ||
        CGSizeEqualToSize(CGSizeZero, size)) {
        return nil;
    }
    NSString *text = content;
    CGRect    rect = CGRectMake(0, 0, size.width, size.height);
    
    CTFontRef myFont = CTFontCreateWithName((__bridge CFStringRef)([font fontName]), [font pointSize], NULL);
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
    [attStr addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attStr.length)];
    
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attStr);
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0, 0, rect.size.width, 100000));
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
    NSMutableArray *linesArray = [[NSMutableArray alloc]init];
    
    for (id line in lines) {
        CTLineRef lineRef = (__bridge CTLineRef )line;
        CFRange lineRange = CTLineGetStringRange(lineRef);
        NSRange range = NSMakeRange(lineRange.location, lineRange.length);
        NSString *lineString = [text substringWithRange:range];
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0]));
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0]));
        [linesArray addObject:lineString];
    }
    CFRelease(frameSetter);
    CFRelease(myFont);
    CFRelease(frame);
    CFRelease(path);
    return (NSArray *)linesArray;
}


@end
